#include "../src/EventHash.h"
#include "../src/EventString.h"
#include "object_v2-hash.h"

#include <stdio.h>
#include <string.h>
#include <time.h>

#define v1 0
#define v2 1000000
#define v3 2000000
#define v4 3000000

static void
generate_data(char *buf, int index)
{
	sprintf(buf, "%d", index);
}

static void
test1(void)
{
	char	     buf[10];
	EventString *str;
	EventHash   *hash = event_hash_new(EVENT_HASH_MODEL_CHARSET);
	event_hash_set_multi_size(hash, 6);

	printf("添加测试数据 ......\n");
	for (int i = v1; i < v2; ++i) {
		generate_data(buf, i);
		str = event_string_new(buf);
		event_hash_set(hash, buf, str, event_object_unref);
	}

	event_hash_print_status(hash);
	printf("读取测试 ......\n");
	for (int i = v1; i < v2; ++i) {
		generate_data(buf, i);
		str = EVENT_STRING(event_hash_get(hash, buf));
		if (!str) {
			printf("测试值 '%s' 时失败，未取得有效值。\n", buf);
			break;
		}
	}

	printf("删除测试 ......\n");
	for (int i = v1; i < v2; ++i) {
		generate_data(buf, i);
		event_hash_remove(hash, buf);
	}

	printf("删除后值获取 ......\n");
	for (int i = v1; i < v2; ++i) {
		generate_data(buf, i);
		str = EVENT_STRING(event_hash_get(hash, buf));
		if (str) {
			printf("测试值 '%s' 时失败，不应取得该值。\n", buf);
			break;
		}
	}

	printf("覆写数据测试 ......\n");
	for (int i = v3; i < v4; ++i) {
		generate_data(buf, i);
		str = event_string_new(buf);
		event_hash_set(hash, buf, str, event_object_unref);
	}

	printf("重读取测试 ......\n");
	for (int i = v3; i < v4; ++i) {
		generate_data(buf, i);
		str = EVENT_STRING(event_hash_get(hash, buf));
		if (str && strcmp(buf, event_string_get_string(str)) == 0) {
			printf("\r比较成功: %s", buf);
		} else {
			printf("测试值 '%s' 时失败，未取得有效值。\n", buf);
			break;
		}
	}
	event_hash_print_status(hash);
	printf("\n迭代测试 ......\n");
	HashItem_p item;
	euint32	   iter_num = 0;
	event_hash_iter_reset(hash);

	do {
		item	  = event_hash_iter_get(hash);
		iter_num += 1;
		if (iter_num == (v4 - v3) / 2)
			event_hash_print_status(hash);
	} while (item);

	if ((iter_num - 1) != (v4 - v3)) {
		printf("迭代数量不一致！测试失败。(迭代: %d, 实际: %d)\n ",
		       iter_num - 1, v4 - v3);
	} else {
		printf("迭代测试没有问题。\n");
	}
	printf("所有测试已完成\n");
	event_object_unref(hash);
}

static void
test2(void)
{
	char	     buf[10];
	EventString *str;
	ObjectHash  *hash = object_hash_new();

	printf("添加测试数据 ......\n");
	for (int i = v1; i < v2; ++i) {
		generate_data(buf, i);
		str = event_string_new(buf);
		object_hash_set_value(hash, buf, false, str,
				      event_object_unref);
	}

	printf("读取测试 ......\n");
	for (int i = v1; i < v2; ++i) {
		generate_data(buf, i);
		str = EVENT_STRING(object_hash_get_value(hash, buf, false));
		if (!str) {
			printf("测试值 '%s' 时失败，未取得有效值。\n", buf);
			break;
		}
	}

	printf("删除测试 ......\n");
	for (int i = v1; i < v2; ++i) {
		generate_data(buf, i);
		object_hash_dest_value(hash, buf, false);
	}

	printf("删除后值获取 ......\n");
	for (int i = v1; i < v2; ++i) {
		generate_data(buf, i);
		str = EVENT_STRING(object_hash_get_value(hash, buf, false));
		if (str) {
			printf("测试值 '%s' 时失败，不应取得该值。\n", buf);
			break;
		}
	}

	printf("覆写数据测试 ......\n");
	for (int i = v3; i < v4; ++i) {
		generate_data(buf, i);
		str = event_string_new(buf);
		object_hash_set_value(hash, buf, false, str,
				      event_object_unref);
	}

	printf("重读取测试 ......\n");
	for (int i = v3; i < v4; ++i) {
		generate_data(buf, i);
		str = EVENT_STRING(object_hash_get_value(hash, buf, false));
		if (str && strcmp(buf, event_string_get_string(str)) == 0) {
			printf("\r比较成功: %s", buf);
		} else {
			printf("测试值 '%s' 时失败，未取得有效值。\n", buf);
			break;
		}
	}
	printf("\n");
	object_unref(hash);
}

int
main(int argc, char **argv)
{
	time_t t[3];
	t[0] = time(NULL);
	printf("测试 EventHash 性能 ......\n");
	test1();
	t[1] = time(NULL);
	printf("测试 ObjectHash 性能 ......\n");
	// test2();
	t[2] = time(NULL);

	printf("测试结果:\nEventHash 用时: %ld s\nObjectHash 用时: %ld s\n",
	       t[1] - t[0], t[2] - t[1]);

	return 0;
}